package com.zee.common.exception;

import com.google.common.collect.ImmutableMap;
import com.zee.common.model.response.CommonCode;
import com.zee.common.model.response.Result;
import com.zee.common.model.response.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * 自定义异常捕获
 *
 * @author Mark LinZee
 * @email LinZee666@163.com
 */
@ControllerAdvice
@Slf4j
public class ExceptionCatch {

    private static ImmutableMap<Class<? extends Exception>, ResultCode> EXCEPTIONS;
    protected static ImmutableMap.Builder<Class<? extends Exception>, ResultCode> builder = ImmutableMap.builder();

    static {
        builder.put(MissingServletRequestParameterException.class, CommonCode.INVALID_PARAM);
        builder.put(EnumConstantNotPresentException.class, CommonCode.INVALID_PARAM);
        builder.put(UnauthorizedException.class, CommonCode.UNAUTHORIZED);
    }

    /**
     * 抛出自定义异常
     *
     * @param customException
     * @return
     */
    @ExceptionHandler(CustomException.class)
    @ResponseBody
    public Result customException(CustomException customException) {
        log.error("catch customException:{}, {}", customException.getResultCode(), customException.getResultCode().message());
        ResultCode resultCode = customException.getResultCode();
        return Result.error(resultCode);
    }

    /**
     * 抛出@Validated的校验的message错误
     *
     * @param exception
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public Result argumentNotValidException(MethodArgumentNotValidException exception) {
        return Result.error(50998, exception.getBindingResult().getAllErrors().get(0).getDefaultMessage());
    }

    /**
     * 抛出框架的异常
     *
     * @param exception
     * @return
     */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Result exception(Exception exception) {
        log.error("catch exception:{}", exception.getMessage());
        if (EXCEPTIONS == null) {
            EXCEPTIONS = builder.build();
        }
        ResultCode resultCode = EXCEPTIONS.get(exception.getClass());

        if (resultCode != null) {
            return Result.error(resultCode);
        } else {
            //打印异常信息
            exception.printStackTrace();
            return Result.error(CommonCode.SERVER_ERROR);
        }
    }
}
